<?php

/*
 * 方法：获取数据源:逻辑控制层
 * 支持几种数据源：1、自定义SQL；2、动态拼凑的数据源；
 * 最终返回：数组
 */

namespace Common\Controller;

/**
 * Description of FetchController
 *
 * @author chenghui caoch
 */
class BdataFetchController extends BdataCoreController {
    
    protected $code='Bdata';//分析代号
    protected $type=0;//0-交叉分析；1-排名分析
    protected $condition=array();//原始条件参数数组：去空值后

    protected $xAxis=array();//x维度-数组：序列化后
    protected $yAxis=array();//y维度-数组：序列化后
    protected $vAxis=array();//v维度-数组：序列化后
    protected $allAxis=array();//所有维度-数组：序列化后
    protected $where='';//w维度-字符串：序列化后
    
    protected $ranking;//排名
    protected $count;//统计

    protected $xNums=0;//x维度数量
    protected $yNums=0;//y维度数量
    protected $vNums=0;//v维度数量
    protected $levelNums=1;//表头层级数

    protected $regionColumn;//区间段参数数组
    protected $DataBase;//表名或数据源SQL
    protected $OriginData;//最原始的数据源SQL
    protected $tempTableArr=array();//临时表记录-数组
    
    protected $DataHead=array();//数据记录-数组[用于临时记录表头数据]
    protected $DataRows=array();//数据记录-数组[用于临时记录产生的数据]
    protected $DataFoot=array();//数据记录-脚注合计
    
    protected $ContrastConfig;//维度的对照-数组
    protected $AxisConfig;//维度配置信息-数组
    protected $AccuracyConfig;//维度的数据精度-数组
    protected $DataBaseConfig;//维度的基础配置-数组
    protected $BdataSpecial;//维度的特殊配置-数组
    protected $UomConfig;//计量单位配置信息-数组
    protected $CountConfig;//统计方式配置信息-数组
    
    protected $decimal;//统计字段小数位精度
    protected $echarts;//图表类型
    protected $isCache;//是否使用缓存
    protected $isScratch;//是否使用数据库缓存

    /**
     * @方法：初始化参数
     * @param type $param
     */
    public function __construct($param){
        //0.初始化分析代号
        $this->code = empty($param['code'])?'Bdata':$param['code'];//需要使用缓存

        //1.初始化分析类型
        $this->type = empty($param['type'])?0:$param['type'];
        $this->isCache = empty($param['isCache'])?1:$param['isCache'];//需要使用缓存
        
        //2.初始化配置表        
        $BaseConfig = new BdataConfigController($this->code,$this->isCache);
        
        $this->DataBaseConfig = $BaseConfig->getDataBaseConfig();
        $this->CountConfig = $BaseConfig->getCountConfig();
        $this->UomConfig = $BaseConfig->getUomConfig();
        
        $this->AxisConfig = $BaseConfig->getAxisConfig();
        $this->ContrastConfig = $BaseConfig->getContrastConfig();
        $this->AccuracyConfig = $BaseConfig->getAccuracyConfig();
        $this->BdataSpecial = $BaseConfig->getBdataSpecial();

        //3.初始化X维度
        if(empty($param['xAxis'])){
            $this->xNums = 0;
        }else{
            $this->xAxis=$this->parseAxis($param['xAxis']);
            $this->xNums = count($this->xAxis);
        }

        //4.初始化Y维度
        if(empty($param['yAxis'])){
            $this->yNums=0;
        }else{
            $this->yAxis=$this->parseAxis($param['yAxis']);
            $this->yNums=count($this->yAxis);
        }

        //5.初始化V维度
        if(empty($param['vAxis'])){
            $this->vNums=0;
        }else{
            $this->vAxis=$this->parseCount($param['vAxis']);
            $this->vNums=count($this->vAxis);
        }

        //6.初始化ranking参数
        if(empty($param['ranking'])){
            $this->ranking=array();
        }else{
            $this->ranking=$param['ranking'];
        }

        //7.初始化count参数
        if(empty($param['count'])){
            $this->count=array();
        }else{
            $this->count=$param['count'];
        }

        //8.除空值后条件数组
        $this->condition = $this->setWipeNull($param['where']);

        //9.初始化条件表达式(不带where关键字)
        $this->where = $this->initWhereCondition();

        //10.设置统计数据的小数位
        $this->decimal=6;

        //11.初始化图表类型：优先取自定义参数，再取配置表，最后取默认值
        if(empty($param['echarts'])){
            $echarts = C('ECHARTS');
            if(empty($echarts)){
                $this->echarts = array(
                                        'bar'=>'柱状图',
                                        'sybar'=>'条形图',
                                        'line'=>'折线图',
                                        'pie'=>'饼状图',
                                        'sline'=>'堆积折线图',
                                        'xBar'=>'堆积柱状图',
                                        'yBar'=>'堆积条形图',
                                        'pxBar'=>'百分比堆积柱状图',
                                        'pyBar'=>'百分比堆积条形图',
                                        'fixed'=>'量价图'
                                    );
            }else{
                $this->echarts = C('ECHARTS');
            }
        }else{
            $this->echarts = $param['echarts'];
        }

        //12.初始化表头层级数
        if($this->vNums==1){
            $this->levelNums = ($this->xNums>0)?$this->xNums:1;
        }else{
            $this->levelNums = ($this->yNums>0)?$this->xNums+1:$this->xNums;
        }
        unset($param);
    }
    
    /**
     * 解析参数中的维度值
     * @access array()
     * @return array()
     */
    private function parseAxis($axis){
        $result = array();

        foreach ($axis as $key=>$val){
            $key = strtoupper($key);
            
            $this->allAxis[]=$key;//记录所有维度值
            
            switch ($this->AxisConfig[$key]['FieldType']){
                case 1://对照表
                    $result[]=$key;
                    break;
                case 2://日期型
                    $result[]=$key;
                    break;
                case 3://统计值
                    $result[]=$key;
                    
                    //追加处理区间段表达式
                    if(!empty($val[1])){//存在单位编码时
                        $rate = (isset($this->UomConfig[$val[1]]['Rate']))?$this->UomConfig[$val[1]]['Rate']:1;
                        
                        $this->regionColumn[$key]=$this->setRegionDetail($val[0],$rate,$this->UomConfig[$val[1]]['UomName']);
                    }else{//无传入编码时，取默认值
                        $this->regionColumn[$key]=$this->setRegionDetail($val,1,$this->AxisConfig[$key]['UomName']);
                    }                    
                    break;
                case 4://文本型
                    $result[]=$key;
                    break;
            }
        }
        return $result;
    }
    
    /**
     * 解析参数中的统计值
     * @access array()：V维度数组
     * @return array()
     */
    private function parseCount($axis){
        $result = array();
        
        foreach ($axis as $k=>$val){
            $key = strtoupper($k);
            
            if ($this->AxisConfig[$key]['FieldType'] == 3){
                if(!empty($val[0])&&!empty($val[1])){
                    $cou=  explode(',', $val[0]);
                    foreach ($cou as $count){
                        $c = strtoupper($count);
                        $result[]=array('k'=>$key,'c'=>$c,'u'=>$val[1]);
                    }
                }
            }
        }
        return $result;
    }
    

        /**
     * 方法：处理条件子句
     * 参数：传入条件数组$where
     * 分支：支持不带关系符的条件，以及带关系符的条件
     * 返回：字符串
     */
    private function initWhereCondition(){
        $nArr = array();
        $wArr = array();

        //1.处理系统配置强制需要的查询条件：主要用于是否去空值
        $nArr = $this->parseIsNullCondition($this->allAxis);
        
        //2.处理参数传入的条件子句：参数处理
        $wArr = $this->parseWhereCondition($this->condition);
        
        $res = array_merge($nArr,$wArr);
        return implode(' and ', $res);
    }

    /**
     * @解析配置表中不允许为空的字段表达式
     * @param type $allAxis
     * @return string
     */
    private function parseIsNullCondition($allAxis){
        $arr = array();
        foreach ($allAxis as $key){
            if($this->AxisConfig[$key]['IsNull']){
                switch ($this->AxisConfig[$key]['FieldType']){
                    case 1:
                    case 3:
                       $arr[] = $this->getCoditionExp($key,$this->AxisConfig).' > 0';
                       break;
                   case 2:
                   case 4:
                       $arr[] = $this->getCoditionExp($key,$this->AxisConfig).' is not null';
                       break;
                }
                
            }
        }
        return $arr;
    }

    /**
     * @解析条件项成最终的条件表达式
     * @param type $where
     * @return type
     */
    private function parseWhereCondition($where){
        $arr = array();
        
        //读取对照表信息
        foreach($where as $key=>$val){
            $column  = $this->getCoditionExp($key,$this->AxisConfig);
            if(is_array($val)){//数组
                if(isset($val['relation'])&&isset($val['values'])){//复杂条件
                    $arr[] = $this->getComplexCodition($column,$val['relation'],$val['values'],$this->AxisConfig[$key]['FieldType'],$this->ContrastConfig[$key]);
                }elseif(isset($val['r'])&&isset($val['v'])){//复杂条件
                    $arr[] = $this->getComplexCodition($column,$val['r'],$val['v'],$this->AxisConfig[$key]['FieldType'],$this->ContrastConfig[$key]);
                }else{//综合查询
                    if(!isset($val['r'])&&!isset($val['v'])){
                        $arr[]=$this->getSimpleCodition($column,$val,$this->AxisConfig[$key]['FieldType'],$this->ContrastConfig[$key]);
                    }                    
                }           
            }else{
                $arr[]=$this->getFastCodition($column,$val,$this->AxisConfig[$key]['FieldType'],$this->ContrastConfig[$key]);
            }            
        }
        return $arr;
    }

     /**
     * @解析SELECT数据源的字段表达式:非统计字段的非统计取值
     * @return type
     */
    private function parseOriginSelectColumn($Axis){
        $resArr = array();
        if(is_array($Axis)){
            foreach ($Axis as $key){
                switch ($this->AxisConfig[$key]['FieldType']){
                    case 1:
                    case 4:
                    default :
                        $resArr[] = $this->AxisConfig[$key]['DataColumn'].' as '.$key;
                        break;
                    case 2:
                        $resArr[] = $this->setDateExp($this->AxisConfig[$key]['Expression'],$this->AxisConfig[$key]['DataColumn']).' as '.$key;
                        $resArr[] = $this->setDateCodeExp($this->AxisConfig[$key]['Expression'],$this->AxisConfig[$key]['DataColumn']).' as D_'.$key;//用于记录日期代号
                        break;
                    case 3:
                        $DataColumn = $this->AxisConfig[$key]['Expression'];
                        if(empty($DataColumn)){//优先考虑表达式
                            $column = $this->AxisConfig[$key]['DataColumn'];
                        }else{
                            if(strpos($DataColumn,'/')){
                                $arr=  explode('/', $DataColumn);
                                $column =  '(case when '.$arr[1].'>0'.' then '.$DataColumn.' else 0 end)';
                            }else{
                                $column = $DataColumn;
                            }
                        }                        
                        $resArr[] = $this->setNumberExp($column,$this->regionColumn[$key]).' as '.$key.'_A';
                        break;
                }
            }
        }
        return implode(',', $resArr);
    }
    
    /**
     * @解析带有特殊处理的字段表达式
     * @param type $FieldCode
     * @param type $Special
     * @return type
     */
    private function parseSpecialOriginSelectColumn($Axis,$FieldCode,$FieldOut){
        $resArr = array();
        if(is_array($Axis)){
            foreach ($Axis as $key){
                if($key == $FieldCode){//存在特殊字段时
                    switch ($this->AxisConfig[$key]['FieldType']){
                        case 1:
                        default :
                            $resArr[] = $FieldOut.' as '.$key;
                            break;
                        case 2:
                            $resArr[] = "'".$FieldOut."'".' as '.$key;
                            $resArr[] = "'".$FieldOut."'".' as D_'.$key;
                            break;
                        case 3:
                            $resArr[] = $this->setNumberExp($this->AxisConfig[$key]['DataColumn'],$this->regionColumn[$key]).' as '.$key;
                            break;
                        case 4:
                            $resArr[] = "'".$FieldOut."'".' as '.$key;
                            break;
                    }
                }else{
                    switch ($this->AxisConfig[$key]['FieldType']){
                        case 1:
                        case 4:
                        default :
                            $resArr[] = $this->AxisConfig[$key]['DataColumn'].' as '.$key;
                            break;
                        case 2:
                            $resArr[] = $this->setDateExp($this->AxisConfig[$key]['Expression'],$this->AxisConfig[$key]['DataColumn']).' as '.$key;
                            $resArr[] = $this->setDateCodeExp($this->AxisConfig[$key]['Expression'],$this->AxisConfig[$key]['DataColumn']).' as D_'.$key;
                            break;
                        case 3:
                            $resArr[] = $this->setNumberExp($this->AxisConfig[$key]['DataColumn'],$this->regionColumn[$key]).' as '.$key;
                            break;
                    }
                }
            }
        }
        return implode(',', $resArr);
    }
    
    
    /**
     * @处理特殊字段表达式
     * @param type $param
     * @return string
     */
    private function parseSpecialWhere($where,$param){
        $wh = $this->parseWhereCondition($param);
        if(!empty($where)){
            $w = $where.' and '.implode(' and ', $wh);
        }else{
            $w = ' where '.implode(' and ', $wh);
        }
        return $w;
    }

    /**
     * @解析数据源中的统计字段表达式：统计值原始取值
     * @return type
     */
    private function parseOriginCountColumn($vAxis){
        if(is_array($vAxis)){
            foreach ($vAxis as $val){
                if(!empty($this->AxisConfig[$val['k']]['DataColumn'])){
                    $resArr[] = $this->AxisConfig[$val['k']]['DataColumn'];
                }else{
                    $res = $this->getCountColumnExp($this->AxisConfig[$val['k']]['Expression'],$val['k'],$this->AxisConfig);
                    if(strpos($res,',')){
                        $arr = explode(',', $res);
                        foreach ($arr as $r){
                            $resArr[] = $r;
                        }                    
                    }else{
                        $resArr[] = $res;
                    }
                }
            }
        }
        $resArr = array_unique($resArr);
        return implode(',', $resArr);
    }

    
    /**
     * @解析最初始的数据源SQL：此处不对统计字段进行处理
     * @return string
     */
    private function getOriginBaseData(){
        //初始化表来源数：以确定SQL是否加表名
        $DataType = strtoupper($this->DataBaseConfig['DataType']);
        
        switch ($this->type){
            case 0:
            case 1:
            case 2:
            case 3:
            default :
                switch ($DataType){
                    case 'TABLE'://表名
                    default :
                        $this->DataBase = $this->getTableGroupData($this->DataBaseConfig['DataExp']);
                        break;
                    case 'SQL'://SQL语句
                        $this->DataBase = $this->getSqlGroupData($this->DataBaseConfig['DataExp']);
                        break;
                    case 'STORED'://存储过程
                        $DataBase = 'Stored_'.date("Ymdhis");
                        $this->tempTableArr[] = $DataBase;

                        $param = $this->DataBaseConfig['Param'];
                        $allAxis = implode(',', $this->allAxis);
                        
                        $bind=$this->setStoredBind($DataBase,$allAxis,$param);
                        M()->prepare($this->DataBaseConfig['DataExp'],$bind);
                        $this->DataBase = $this->getStoredGroupData($DataBase);
                        break;
                }
                break;
            case 9://挖掘数据时，只允许从物理表或数据仓库取数
                $this->DataBase = $this->getTableGroupData($this->DataBaseConfig['DigTable']);
                break;
        }        
    }
    
    
    /**
     * @说明：将条件参数转换成bind参数数组。仅用于存储过程的调用
     * @param type $DataBaseParam
     * @return string
     */
    private function setStoredBind($DataBase,$allAxis,$DataBaseParam){
        $bind=array();
        $array = explode(';', $DataBaseParam);
        foreach ($array as $v){
            $line = explode('=', $v);
            $key = $line[0];
            $val = $line[1];

            if($val=='T'){//常量：表示数据表名
                $bind[$key]=$DataBase;
            }elseif($val=='allAxis'){//表示维度
                $bind[$key]=$allAxis;
            }else{
                if(strpos($val,':')){//存在区间段值时，设定0为最小值，1为最大值
                    $arr = explode(':', $val);
                    $k = strtoupper($arr[0]);
                    $values = $this->condition[$k][$arr[1]];
                    $bind[$key]=  !empty($values)?$values:'';
                }else{
                    $k = strtoupper($val);
                    if(isset($this->condition[$k])){
                        if(is_array($this->condition[$k])){
                            $bind[$key] = implode(',', $this->condition[$k]);
                        }else{
                            $bind[$key] = $this->condition[$k];
                        }
                    }else{
                        $bind[$key]=  '';
                    }
                }
            }
        }
        return $bind;
    }

    /**
     * @解析数据源（含统计结果）:当数据源为数据表时
     * @param type $DataBase 数据表名
     * @return string
     */
    private function getTableGroupData($DataBase){                
        //1.基础表数据读取
        $where = (empty($this->where))?' ':' where '.$this->where;
        $this->OriginData = 'select '.$this->parseOriginSelectColumn($this->allAxis).','.$this->parseOriginCountColumn($this->vAxis).' from '.$DataBase.$where;

        //2.表示存在特殊计算字段:计算特殊表达式的数据读取
        $SpecialArr = $this->setBdataSpecialSql($DataBase,$where,$this->allAxis,$this->allAxis,$this->vAxis);
        
        if(!empty($this->OriginData)){
            if(!empty($SpecialArr)){
                $this->OriginData .= ' union all '.implode(' union all ', $SpecialArr);
            }            
        }else{
            if(!empty($SpecialArr)){
                $this->OriginData = implode(' union all ', $SpecialArr);
            }            
        }        
        
        //3.计算统计结果
        $result = 'select '.$this->setSelectColumnExp($this->AxisConfig,$this->allAxis).','
                  .$this->setCountColumnExp($DataBase,$where,$this->AxisConfig,$this->UomConfig,$this->vAxis)
                  .' from '.'('.$this->OriginData.')'.' as OT'
                  .' group by '.$this->setGroupByColumnExp($this->AxisConfig,$this->allAxis);
        
        return $result;
    }
    
    /**
     * @解析数据源:当数据源配置为SQL语句时
     * @return string
     */
    private function getSqlGroupData($DataBase){
                
        //1.基础表数据读取
        $where = (empty($this->where))?' ':' where '.$this->where;

        $this->OriginData = $DataBase.$where;
        
        //3.计算统计结果
        $result = 'select '.$this->setSelectColumnExp($this->AxisConfig,$this->allAxis).','
                  .$this->setCountColumnExp($DataBase,$where,$this->AxisConfig,$this->UomConfig,$this->vAxis)
                  .' from '.'('.$this->OriginData.')'.' as OT'
                  .' group by '.$this->setGroupByColumnExp($this->AxisConfig,$this->allAxis);
        
        return $result;
    }
    
    /**
     * @解析数据源（含统计结果）
     * @return string
     */
    private function getStoredGroupData($DataBase){
                
        //1.基础表数据读取
        $wh = $this->parseIsNullCondition($this->allAxis);
        
        if(empty($w)){
            $where = '';
        }else{
            $where = implode(' and ', $wh);
        }
        
        $this->OriginData = 'select '.$this->parseOriginSelectColumn($this->allAxis).','.$this->parseOriginCountColumn($this->vAxis).' from '.$DataBase.$where;

        //2.表示存在特殊计算字段:计算特殊表达式的数据读取
        $SpecialArr = $this->setBdataSpecialSql($DataBase,$where,$this->allAxis,$this->allAxis,$this->vAxis);
        
        if(!empty($this->OriginData)){
            if(!empty($SpecialArr)){
                $this->OriginData .= ' union all '.implode(' union all ', $SpecialArr);
            }            
        }else{
            if(!empty($SpecialArr)){
                $this->OriginData = implode(' union all ', $SpecialArr);
            }            
        }
        
        //3.计算统计结果
        $result = 'select '.$this->setSelectColumnExp($this->AxisConfig,$this->allAxis).','
                  .$this->setCountColumnExp($DataBase,$where,$this->AxisConfig,$this->UomConfig,$this->vAxis)
                  .' from '.'('.$this->OriginData.')'.' as OT'
                  .' group by '.$this->setGroupByColumnExp($this->AxisConfig,$this->allAxis);

        return $result;
    }
    
    /**
     * @解析统计字段统计时的表达式
     * @param type $DataBase 数据表
     * @param type $where 默认条件
     * @param type $AxisConfig 维度配置
     * @param type $uomArr 计量单位配置
     * @param type $vAxis 统计字段
     * @return type
     */
    private function setCountColumnExp($DataBase,$where,$AxisConfig,$uomArr,$vAxis){
        $res = array();
        foreach($vAxis as $val){
            if($val['c']=='RATE'){
                $key = $val['k'];
                if(!empty($AxisConfig[$key]['DataColumn'])){
                    $totalSql = $this->setBdataRateSql($DataBase,$where,$key);
                    $res[] = $this->setRateCount($key,$AxisConfig[$key]['DataColumn'],$totalSql);
                }
            }else{
                $res[] = $this->setCount($AxisConfig,$uomArr,$val);
            }
        }
        return implode(',', $res);
    }
    
    /**
     * @解析特殊计算数据的SQL
     * @param type $where
     * @param type $allAxis
     * @param type $Axis
     * @param type $vAxis
     * @return string
     */
    private function setBdataSpecialSql($DataBase,$where,$allAxis,$Axis,$vAxis){
        $OriginData = array();
        
        foreach ($this->BdataSpecial as $val){
            if(in_array($val['FieldCode'], $allAxis)){
                $param = array($val['FieldColumn']=>array('r'=>$val['FieldExp'],'v'=>$val['FieldValue']));
                $cWhere = $this->parseSpecialWhere($where,$param);

                $OriginData[] = 'select '.$this->parseSpecialOriginSelectColumn($Axis,$val['FieldCode'],$val['FieldOut']).','.$this->parseOriginCountColumn($vAxis).' from '.$DataBase.$cWhere; 
            }
        }
        return $OriginData;
    }
    
    /**
     * @处理占比时，合计数据源与主表数据的WHERE关系
     * @param type $left 当前表别名
     * @param type $right 主表别名
     * @param type $Axis 维度值
     * @return type
     */
    private function setBdataGX($left,$right,$Axis){
        $res = array();
        foreach($Axis as $key){
            $res[] = $left.'.'.$key.'='.$right.'.'.$key;
        }
        return implode(' and ', $res);
    }

    /**
     * @此方法仅用于含有占比计算的统计方法时
     * @param type $key
     * @return string
     */
    private function setBdataRateSql($DataBase,$where,$key){

        if($this->xNums > 0){//存在横向坐标时
            if($this->yNums>0){//存在纵向坐标
                //构造V数组
                $array[] = array('k'=>$key,'c'=>'SUM','u'=>$this->AxisConfig[$key]['Uom']);
                //原始表
                $sql0 = 'select '.$this->parseOriginSelectColumn($this->xAxis).','.$this->parseOriginCountColumn($array).' from '.$DataBase.$where;

                //特殊数据处理            
                $SpecialArr = $this->setBdataSpecialSql($where,$this->allAxis,$this->xAxis,$array);
                if(!empty($SpecialArr)){
                    $sql0 .= implode(' union all ', $SpecialArr);
                }
                
                //统计数据
                $sql3 = 'select '
                        .$this->setSelectColumnExp($this->AxisConfig,$this->xAxis).','
                        .$this->setCountColumnExp($DataBase,$where,$this->AxisConfig,$this->UomConfig,$array)
                        .' from '.'('.$sql0.')'.' as a'
                        .' group by '.$this->setGroupByColumnExp($this->AxisConfig,$this->xAxis);
                
                //与主表关联
                $sql = 'select '.$this->setCountColumnFormats($key, 'SUM')
                        .' from '.'('.$sql3.')'.' as RT'
                        .' where '.$this->setBdataGX('RT','OT',$this->xAxis);
                
            }else{//无纵向坐标
                $sql = 'select '.'sum('.$this->AxisConfig[$key]['DataColumn'].')'.' as Total'.' from '.$DataBase.$where;
            }
        }else{//不存在横坐标，但必有纵坐标
            $sql = 'select '.'sum('.$this->AxisConfig[$key]['DataColumn'].')'.' as Total'.' from '.$DataBase.$where;
        }
        
        return $sql;
    }
    

    /**
     * @解析交叉分析数据
     * @return type
     */
    protected function getAnalyzeMainData(){
        $result = array();        

        //提数据源SQL,返回源数据SQL
        $this->getOriginBaseData();
//        echo $this->DataBase;
//        
//        exit();
        if($this->xNums>0){//存在表头维度
            if($this->yNums>0){//存在y维度
                $result = $this->getgetAnalyzeChildXYVData();
            }else{//仅有X轴时
                $result = $this->getgetAnalyzeChildOlnyXData();
            }            
        }else{//无x轴
            $result = $this->getgetAnalyzeChildNoXData();
        }
        return $result;
    }
    


    /**
     * @交叉分析取数子方法：专用于同时存在XYV轴的数据
     * @return array
     */
    private function getgetAnalyzeChildXYVData(){
        //获得表头数组
        $result['head'] = $this->setHeaderXYData();

        //获取表体数组
        foreach ($this->vAxis as $val){
            $vResult[] = $this->setCountColumnFormats($val['k'], $val['c']);
        }
        
        $param = array('code'=>$this->code,'db'=>$this->DataBase,'vAxis'=>$this->DataHead,'decimal'=>$this->decimal);
        $Axis = array('xAxis'=>$this->xAxis,'yAxis'=>$this->yAxis,'vAxis'=>$vResult); 

        $data = $this->getXYVAxisData($param,$Axis,$this->regionColumn);

        $result['rows'] = $this->setAddSumDataRowsFormat($data);

        //获得表脚数组
        if($this->count['isYSum']==1){
            $result['foot'] = $this->setDataFootFormat();
        }else{
            $result['foot'] = array();
        }
        return $result;
    }
    
    /**
     * @交叉分析取数子方法：专用于仅含X轴的数据
     * @return array
     */
    private function getgetAnalyzeChildOlnyXData(){
        //原始数据：表头数据与表体数据一起返回
        $result['head'] = $this->setHeaderNoYAxis();
        $result['rows'] = $this->setNotYSumDataRowsFormat($this->DataRows);
        $result['foot'] = array();
        return $result;
    }

    /**
     * @交叉分析取数子方法：专用于获取无X轴的数据
     * @return type
     */
    private function getgetAnalyzeChildNoXData(){
        //获得表头数组
        $head = $this->setHeaderNoXAxis();

        //表头ID与CODE
        foreach($this->DataHead as $key=>$val){
            $vAxis[] = $key.' as '.$val['f'];
        }

        //获取表体数组
        $param = array('code'=>$this->code,'db'=>$this->DataBase,'x'=>false);
        $Axis = array('Axis'=>$this->yAxis,'vAxis'=>$vAxis);          

        $data = $this->getOnlyOneAxisData($param,$Axis,$this->regionColumn);
        $rows = $this->setNotXSumDataRowsFormat($data);

        //获得表脚数组
        if($this->count['isYSum']==1){
            $foot = $this->setDataFootFormat();
        }else{
            $foot = array();
        }

        $result = array('head'=>$head,'rows'=>$rows,'foot'=>$foot);
        
        return $result;
    }

    
    /**
     * @解析挖掘数据
     * @return type
     */
    protected function getDigMainData(){
        //提数据源SQL,返回源数据SQL
        $this->getOriginBaseData();        

        //获得表头数组
        $head = $this->setHeaderNoXAxis();
        
        foreach($this->DataHead as $key=>$val){
            $vAxis[] = $key.' as '.$val['f'];
        }

        //获取表体数组
        $param = array('code'=>$this->code,'db'=>$this->DataBase,'x'=>false);
        $ranking = array('topNum'=>$this->ranking['topNum'],'topColumn'=>$this->ranking['topColumn']);
        $Axis = array('Axis'=>$this->yAxis,'vAxis'=>$vAxis);

        $data = $this->getTopSingleAxisData($param,$ranking,$Axis,$this->regionColumn);

        $rows = $this->setNotXSumDataRowsFormat($data);

        $result = array('head'=>$head,'rows'=>$rows,'foot'=>array());

        return $result;
    }
    
    
    /**
     * @解析排行分析数据
     * @return type
     */
    protected function getToppicMainData(){
        //提数据源SQL,返回源数据SQL
        $this->getOriginBaseData();

        //获得表头数组
        $head = $this->setHeaderNoXAxis();        
        
        //多个排行分析维度
        if($this->yNums>1){
            foreach($this->DataHead as $key=>$val){
                $vAxis[] = $key.' as '.$val['f'];
            }
            
            //获取表体数组
            $param = array('code'=>$this->code,'db'=>$this->DataBase,'x'=>false);
            $ranking = array('topNum'=>$this->ranking['topNum'],'topColumn'=>$this->ranking['topColumn']);
            $Axis = array('Axis'=>$this->yAxis,'vAxis'=>$vAxis);
            
            $data = $this->getTopMultiAxisData($param,$ranking,$Axis,$this->regionColumn);
            
            $rows = $this->setNotXSumDataRowsFormat($data);
            
            $result = array('head'=>$head,'rows'=>$rows,'foot'=>array());
        }else{
            foreach($this->DataHead as $key=>$val){
                $vAxis[] = $key.' as '.$val['f'];
            }
            
            //获取表体数组
            $param = array('code'=>$this->code,'db'=>$this->DataBase,'x'=>false);
            $ranking = array('topNum'=>$this->ranking['topNum'],'topColumn'=>$this->ranking['topColumn']);
            $Axis = array('Axis'=>$this->yAxis,'vAxis'=>$vAxis);
        
            $data = $this->getTopSingleAxisData($param,$ranking,$Axis,$this->regionColumn);
            
            $rows = $this->setNotXSumDataRowsFormat($data);
            
            $result = array('head'=>$head,'rows'=>$rows,'foot'=>array());
        }
        return $result;
    }
    
    /**
     * @解析同比环比数据
     * @return type
     */
    protected function getRatioMainData(){
        
        return $result;
    }

        /**
     * @方法：专门用于解析左侧表头数据表达式
     * @return int
     */
    private function setLeftHeader(){
        $Lhead = array();
        
        if($this->xNums>0){//存在X轴
            if($this->yNums>0){
                foreach ($this->yAxis as $key){
                    $Lhead[$key] = array('f'=>$key,'t'=>$this->AxisConfig[$key]['FieldName'],'c'=>1);
                }
            }else{
                $Lhead['yAxis'] = array('f'=>'yAxis','t'=>$this->AxisConfig['yAxis']['FieldName'],'c'=>1);
            }
        }else{//不存在X轴
            //排名分析时，最左侧追加序号
            if($this->type == 1){
                if($this->yNums > 1){//多维度时，在倒数第一个维度前加排名
                    //Y轴数组
                    $i=1;
                    foreach ($this->yAxis as $key){
                        if($i == $this->yNums){//最后一个维度时，在前面追加一个排名列
                            $Lhead['rank'] = array('f'=>'rank','t'=>$this->AxisConfig['rank']['FieldName'],'c'=>1);
                        }
                        $Lhead[$key] = array('f'=>$key,'t'=>$this->AxisConfig[$key]['FieldName'],'c'=>1);
                        ++$i;
                    }
                }else{//单维度时，第一列为排名
                    $Lhead['rank'] = array('f'=>'rank','t'=>$this->AxisConfig['rank']['FieldName'],'c'=>1);
                    //Y轴数组
                    foreach ($this->yAxis as $key){
                        $Lhead[$key] = array('f'=>$key,'t'=>$this->AxisConfig[$key]['FieldName'],'c'=>1);
                    }
                }
            }else{
                //Y轴数组
                foreach ($this->yAxis as $key){
                    $Lhead[$key] = array('f'=>$key,'t'=>$this->AxisConfig[$key]['FieldName'],'c'=>1);
                }
            }
        }
        return $Lhead;
    }

    /**
     * @解析右侧表头数组
     * @return type
     */
    private function setRigthHeader(){
        //注意此处顺序，排在前面的为分组项
        if($this->xNums>0){
            if($this->yNums>0){//同时存在XY轴
                if($this->levelNums>1){//多层表头时
                    for($i=1;$i<$this->levelNums;$i++){
                        $id[] = 'sums';
                        $title[] = $this->AxisConfig['sums']['FieldName'];
                    }
                    $i = implode('@', $id);
                    $t = implode('@', $title);

                    foreach ($this->vAxis as $val){
                        $id = $i.'@'.$this->setCountColumnFormats($val['k'], $val['c']);
                        $title = $t.'@'.$this->parseCountName($val, $this->AxisConfig, $this->CountConfig, $this->UomConfig);

                        $Rhead[$id] = array('f'=>$this->setCountColumnFormats($val['k'], $val['c']),'t'=>$title,'c'=>1);
                    }
                }else{//单层表头
                    $Rhead['sums'] = array('f'=>'sums','t'=>$this->AxisConfig['sums']['FieldName'],'c'=>1);
                }
            }else{//仅X轴
                if($this->levelNums>1){//多层表头时
                    for($i=0;$i<$this->levelNums;$i++){
                        $id[] = 'sums';
                        $title[] = $this->AxisConfig['sums']['FieldName'];
                    }
                    $i = implode('@', $id);
                    $t = implode('@', $title);
                    $Rhead[$i] = array('f'=>'sums','t'=>$t,'c'=>1);
                }else{
                    $Rhead['sums'] = array('f'=>'sums','t'=>$this->AxisConfig['sums']['FieldName'],'c'=>1);
                }                
            }            
        }else{//仅Y轴
            $Rhead = array();
        }        
        
        return $Rhead;
    }

    /**
     * @不存在X轴时，解析表头数组[此时仅只能存在一层表头]
      * @返回：格式化的表头数组：包含右侧合计
      * @返回：$this->DataHead：记录表头field与id
     */
    protected function setHeaderNoXAxis(){
        //左侧栏目
        $Lhead = $this->setLeftHeader();
        
        //表头数据
        $i=0;
        foreach ($this->vAxis as $val){
            //字段ID：用于挖掘时识别的表达式
            $key = $this->setCountColumnFormats($val['k'], $val['c']);
            //字段FIELD：用于表格展示时的代号，为了节省返回数据的容量，同时兼顾输出数据精度要求，代号作转义处理
            $field = $this->setCountCode($key,$this->AccuracyConfig[$val['k']]['Accuracy']);
            $field .=$i;
            //字段TITLE：表格展示时显示的名称
            $title = $this->parseCountName($val,$this->AxisConfig,$this->CountConfig,$this->UomConfig);
            //用于记录表头输出格式所需的参数
            $Mhead[$key] = array('f'=>$field,'t'=>$title,'c'=>1);
            //记录表头ID与FIELD数组，用于统一表头与表体的代号一致性
            $this->DataHead[$key] = array('c'=>$key,'f'=>$field);
            
            ++$i;
        }
        
        //右侧表头:此情况时无需右侧合计
        $Rhead = $this->setRigthHeader();
        
        //表头层级数：此时永远只有一层        
        $result = $this->setHeaderLevelArray($this->levelNums,$Lhead,$Mhead,$Rhead,1);
        
        return $result;
    }
    
    
    /**
     * @不存在Y轴时，解析表头数组[有可能存在多层表头]
     * @返回：表头带输出格式的数组
     * @返回：所有数据内容数组
     */
    private function setHeaderNoYAxis(){        
        //1.原始数据集
        foreach ($this->vAxis as $val){
            $vAxis[] = $this->setCountColumnFormats($val['k'], $val['c']);
        }
        
        $param = array('code'=>$this->code,'db'=>$this->DataBase,'x'=>true);
        $Axis = array('Axis'=>$this->xAxis,'vAxis'=>$vAxis);  
        
        $array = $this->getOnlyOneAxisData($param,$Axis,$this->regionColumn);

        //2.数据精度
        $Accuracy = $this->setNumberAccuracy($this->AccuracyConfig,$this->vAxis);
        //解析左侧表头
        $Lhead = $this->setLeftHeader();
        
        //当需要右侧合计时，读取右侧合计值
        if($this->count['isXSum']==1){
            $data = $this->getRightSumData($this->DataBase,$this->yAxis,$this->xAxis,$this->vAxis);
        }        
        
        //3.提取出数据固定的id和yaxis值
        foreach ($this->vAxis as $v){
            $key = $this->setCountColumnFormats($v['k'], $v['c']);

            $this->DataRows[$key]['id'] = $key;
            $this->DataRows[$key]['yAxis'] = $this->parseCountName($v,$this->AxisConfig,$this->CountConfig,$this->UomConfig);
        }
        
        $i=0;
        //4.将每行数据暂存到临时数据变量
        foreach($array as $val){
            $field = 'T'.$i;
            $Mhead[$val['id']] = array('f'=>$field,'t'=>$val['yAxis'],'c'=>1);
            
            //每一行的统计值做转向处理
            foreach ($this->vAxis as $v){
                $key = $this->setCountColumnFormats($v['k'], $v['c']);

                $this->DataRows[$key][$field] = $this->setNumberFormat($val[$key],$Accuracy[$key]);
                
                if($this->count['isXSum']==1){
                    $this->DataRows[$key]['sums'] = $this->setNumberFormat($data[0][$key],$Accuracy[$key]);
                }                
            }            
            ++$i;
        }

        //需要右侧表头时
        if($this->count['isXSum']==1){
            $Rhead = $this->setRigthHeader();
        }
        
        //4.当存在多层时，需要处理成多层表头
        $result = $this->setHeaderLevelArray($this->levelNums,$Lhead,$Mhead,$Rhead,1);

        return $result;
    }
    
    
    /**
     * @格式化表头数组【同时存在X与Y】
     * @return type
     */
    private function setHeaderXYData(){
        //1.左侧栏目:Y轴数组
        $Lhead = $this->setLeftHeader();
        
        //2.主要表头数据
        $param = array('code'=>$this->code,'db'=>$this->DataBase,'x'=>true);
        $Axis = array('Axis'=>$this->xAxis);
        
        $data = $this->getHeadDataResult($param,$Axis,$this->regionColumn);
        
        //3.核心数据格式
        if($this->vNums>1){//多个统计值
            $colspan = $this->vNums;
            $Mhead = $this->setMultiVHeadFormat($data,$this->vAxis);
        }else{//单个统计值
            $colspan =1;
            $Mhead = $this->setOnlyOneVHeadFormat($data,$this->vAxis);
        }
        
        //4.右侧表头   
        if($this->count['isXSum']==1){
            $Rhead = $this->setRigthHeader();
        }        
        
        $result = $this->setHeaderLevelArray($this->levelNums,$Lhead,$Mhead,$Rhead,$colspan);
        return $result;
    }
    
    /**
     * @通用方法：读取表头数组[仅只有一个统计方式时]
     * @param type $param 数组，包含关键字：db数据表名,code代号,x是否为X维度
     * @param type $Axis 数组，包含Axis非统计字段
     * @param type $regionColumn 数组，区间段数组
     * @return type
     */
    private function getHeadDataResult($param,$Axis,$regionColumn=array()){
        //初始化参数
        $code = $param['code'];
        $DataBase = $param['db'];
        
        $xAxis = $Axis['Axis'];
        
        //解析中文含义
        $Inner = $this->getInnerData($code,$xAxis,$regionColumn);
        
        //解析ID
        if(count($xAxis) > 1){
            $id = implode("+'@'+", $Inner['id']).' as id';
            $BCode = implode("+'@'+", $Inner['BCode']).' as BCode';
        }else{
            $id = implode(',',$Inner['id']).' as id';
            $BCode = implode(',',$Inner['BCode']).' as BCode';
        }
        
        //增加日期的别称
        $resAxis = $this->parseAxisCode($xAxis);
        $rsele = implode(',', $resAxis);
        $select = implode("+'@'+", $Inner['name']).' as xAxis';
        
        //取非重复的值
        $QSql = 'select '
                .$rsele
                .' from ('.$DataBase.') as tp '
                .' group by '.$rsele;
        
        //获取数据的SQL
        $sql = 'select '.$id
                .','.$BCode
                .','.$select
                .' from ('.$QSql.') as tptp '
                .implode(' ', $Inner['inner'])
                .' order by '.implode(',', $Inner['order']); 

        $result = M()->query($sql);
        
        return $result;
    }
    
    
    /**
     * @获取表头格式【用于同时存在XY，V只一个统计值时】
     * @param type $data
     * @param type $vAxis 字符串：统计方式JZMJ_SUM
     * @return type
     */
    private function setOnlyOneVHeadFormat($data,$vAxis){
        $i=0;
        
        foreach ($vAxis as $val){
            $key = $this->setCountColumnFormats($val['k'], $val['c']);
        }
        
        $f = $this->setCountCode($key,$this->AccuracyConfig[$val['k']]['Accuracy']);

        foreach($data as $val){            
            $field =$f.$i;
            //表头数组
            $result[$val['BCode']] = array('f'=>$field,'t'=>$val['xAxis'],'c'=>1);
            //记录表头ID与FIELD数组，用于统一表头与表体的代号一致性
            $this->DataHead[$val['id']] = array('c'=>$val['BCode'],'f'=>$field);
            //$this->DataHead[$val['BCode']] = array('c'=>$val['id'],'f'=>$field);
            ++$i;
        }
        return $result;
    }
    
    /**
     * @获取表头格式【用于同时存在XY，V多个统计值时】
     * @param type $data
     * @param type $vAxis 字符串：统计方式JZMJ_SUM
     * @return type
     */
    private function setMultiVHeadFormat($data,$vAxis){
        $i=0;
        
        //根据统计值，初始化每个字段的精度首字母
        foreach ($vAxis as $val){
            $key = $this->setCountColumnFormats($val['k'], $val['c']);
            $code[$key] = $this->setCountCode($key,$this->AccuracyConfig[$val['k']]['Accuracy']);
            $name[$key] = $this->parseCountName($val, $this->AxisConfig, $this->CountConfig, $this->UomConfig);
        }                

        foreach($data as $val){
            foreach($code as $key=>$value){
                $id = $val['BCode'].'@'.$key;
                $field =$value.$i;
                $title = $val['xAxis'].'@'.$name[$key];
                //表头数组
                $result[$id] = array('f'=>$field,'t'=>$title,'c'=>1);
                //记录表头ID与FIELD数组，用于统一表头与表体的代号一致性
                $this->DataHead[$id] = array('c'=>$id,'f'=>$field);
                
                ++$i;
            }
        }
        return $result;
    }

    /**
     * @拼凑中文字段的表达式
     * @param type $code
     * @param type $Axis
     * @param type $regionColumn
     * @return type
     */
    private function getInnerData($code,$Axis,$regionColumn){
        $i=0;
        foreach ($Axis as $key){
            $tb='tb'.$i;
            switch ($this->ContrastConfig[$key]['FieldType']){
                case 1:
                    $ID[] = 'cast('.$tb.'.'.$this->ContrastConfig[$key]['ContrastId'].' as varchar(10))';
                    $BCode[] = 'cast('.$tb.'.'.$this->ContrastConfig[$key]['ContrastId'].' as varchar(10))';
                    $select[] = $tb.'.'.$this->ContrastConfig[$key]['ContrastName'].' as '.$key;
                    $name[] = $tb.'.'.$this->ContrastConfig[$key]['ContrastName'];
                    $inner[] = 'inner join '.$this->ContrastConfig[$key]['ContrastSheet'].' as '.$tb.' on '.$tb.'.'.$this->ContrastConfig[$key]['ContrastId'].'='.$key;
                    $order[] = $tb.'.'.$this->ContrastConfig[$key]['ContrastSort'];
                    break;
                case 3://区间
                    //1.创建区间段的临时表
                    $Region = $this->createRegionTempTable($key,$regionColumn[$key]);
                    $this->tempTableArr[] = $Region;
                    
                    $ID[] = 'cast('.$tb.'.id'.' as varchar(40))';
                    $BCode[] = 'cast('.$tb.'.code'.' as varchar(40))';
                    $select[] = $tb.'.title'.' as '.$key; 
                    $name[] = $tb.'.title'; 
                    $inner[] = 'inner join '.$Region.' as '.$tb.' on '.$tb.'.id'.'='.$key;
                    $order[] = $tb.'.id';
                    break;
                case 2://日期
                    $ID[] = 'D_'.$key;
                    $BCode[] = 'D_'.$key;
                    $select[]=$key;
                    $name[]=$key;
                    $inner[]='';
                    $order[]=$key;
                    break;
                case 4:
                default :
                    $ID[] = $key;
                    $BCode[] = $key;
                    $select[]=$key;
                    $name[]=$key;
                    $inner[]='';
                    $order[]=$key;
                    break;
            }
            ++$i;
        }
        return array('id'=>$ID,'select'=>$select,'name'=>$name,'inner'=>$inner,'order'=>$order,'group'=>$group,'BCode'=>$BCode);
    }
    
    
    /**
     * @通用方法：读取只有一个维度时的数据
     * @param type $param 数组，包含关键字：db数据表名,code代号,x是否为X维度
     * @param type $Axis 数组，包含Axis非统计字段,vAxis统计字段
     * @param type $regionColumn 数组，区间段数组
     * @return type
     */
    private function getOnlyOneAxisData($param,$Axis,$regionColumn=array()){
        //初始化参数
        $x = $param['x'];
        $code = $param['code'];
        $DataBase = $param['db'];
        
        $xAxis = $Axis['Axis'];
        $vAxis = $Axis['vAxis'];
        
        //解析中文含义
        $Inner = $this->getInnerData($code,$xAxis,$regionColumn);
        
        //解析ID
        if(count($xAxis) > 1){
            $id = implode("+'@'+", $Inner['BCode']).' as id';
        }else{
            $id = implode(',',$Inner['BCode']).' as id ';
        }
        
        if($x){//x维度
            $select = implode("+'@'+", $Inner['name']).' as yAxis';
        }else{//y维度
            $select = implode(',', $Inner['select']);
        }

        $sql = 'select '.$id
                .','.$select
                .','.implode(',', $vAxis)
                .' from ('.$DataBase.') as tp '
                .implode(' ', $Inner['inner'])
                .' order by '.implode(',', $Inner['order']); 

        $result = M()->query($sql);
        
        return $result;
    }
    
    /**
     * @返回排名数据:单个Y轴时
     * @return type
     */
    public function getTopSingleAxisData($param,$ranking,$Axis,$regionColumn=array()){
        $result = array();
        //初始化参数
        $topNum = $ranking['topNum'];
        $topColumn = $this->setCountColumnFormats($ranking['topColumn'][0], $ranking['topColumn'][1]);

        $order = $ranking['topColumn'][2];
        
        $DataBase = $param['db'];
        $code = $param['code'];
        
        $xAxis = $Axis['Axis'];
        $vAxis = $Axis['vAxis'];
        
        if(!empty($topColumn)){            
            $topNum = !empty($topNum)?$topNum:10;
            $orderby = $topColumn.' '.$order; 
            
            //解析中文含义
            $Inner = $this->getInnerData($code,$xAxis,$regionColumn);

            //解析ID
            $id = implode(',',$Inner['BCode']).' as id ';

            $sql = 'select top '.$topNum
                    .' ROW_NUMBER() OVER(ORDER BY '.$orderby.') as rank,'
                    .$id
                    .','.implode(',', $Inner['select'])
                    .','.implode(',', $vAxis)
                    .' from ('.$DataBase.') as tp '
                    .implode(' ', $Inner['inner'])
                    .' order by '.$orderby; 

            $result = M()->query($sql);
        }
        
        return $result;
    }

    /**
     * @返回排名数据：多个Y轴时【存在分组时】
     * @return type
     */
    public function getTopMultiAxisData($param,$ranking,$Axis,$regionColumn=array()){
        $result = array();
        //初始化参数
        $topNum = $ranking['topNum'];
        $topColumn = $this->setCountColumnFormats($ranking['topColumn'][0], $ranking['topColumn'][1]);
        $order = $ranking['topColumn'][2];
        
        $DataBase = $param['db'];
        $code = $param['code'];
        
        $xAxis = $Axis['Axis'];
        $vAxis = $Axis['vAxis'];
        
        if(!empty($topColumn)){            
            $topNum = !empty($topNum)?$topNum:10;
            $orderby = $topColumn.' '.$order; 
            
            $col=array();
            $i=1;
            $nums = count($xAxis);
            foreach ($xAxis as $key){
                if($i < $nums){
                   $col[]='tttt.'.$key; 
                   //用于结果排序依据
                   $rOrder[]=$key;
                }else{
                   $rOrder[]='seq_num';
                }
                ++$i;
            }

            $partition = implode(',', $col);
            
            $res = 'select tttt.*,'
                .'dense_rank() over (partition by '.$partition.' order by '.$orderby.' ) as seq_num '
                .' from ('
                .$DataBase.') as tttt';

            //解析中文含义
            $Inner = $this->getInnerData($code,$xAxis,$regionColumn);

            //解析ID
            $id = implode("+'@'+", $Inner['BCode']);
            
            $sql = 'select '
                .$id.' as id '
                .','.implode(',', $Inner['select'])
                .','.implode(',', $vAxis)
                .','.'seq_num as rank'
                .' from ('
                .$res
                .') as tttt2 '
                .implode(' ', $Inner['inner'])
                .' where seq_num <= '.$topNum
                .' order by '.  implode(',', $rOrder);

            $result = M()->query($sql);
        }
        return $result;
    }
       
    /**
     * @解析同时存在X,Y,V三个维度的数据
     * @param type $param
     * @param type $Axis
     * @param type $regionColumn
     * @return type
     */
    private function getXYVAxisData($param,$Axis,$regionColumn=array()){
        $vAxis = $Axis['vAxis'];

        if(count($vAxis)>1){//多个统计值
            $result = $this->setMultiVAxisData($param,$Axis,$regionColumn);
        }else{//单个统计值
            $result = $this->setOnlyOneVAxisData($param,$Axis,$regionColumn);
        }
        
        return $result;
    }
    
    /**
     * @解析X维度SELECT表达式
     * @param type $xAxis
     * @param type $isSingle
     * @return string
     */
    private function setXAxisSelectExp($xAxis,$isSingle){
        $res = array();
        
        foreach ($xAxis as $key){
            switch ($this->AxisConfig[$key]['FieldType']){
                case 1:
                case 3:
                default :
                    if($isSingle&&count($xAxis)==1){
                        $res[] = $key;
                    }else{
                        $res[] = 'cast('.$key.' as varchar(40))';
                    }                    
                    break;
                case 2:
                    if($isSingle&&count($xAxis)==1){
                        $res[] = 'D_'.$key;
                    }else{
                        $res[] = 'cast(D_'.$key.' as varchar(40))';
                    }                    
                    break;
                case 4:
                    $res[] = $key;
                    break;
            }
        }
        
        return $res;
    }

    
    /**
     * @获取单个统计值的数据源
     * @param type $param
     * @param type $Axis
     * @param type $regionColumn
     * @return type
     */
    private function setOnlyOneVAxisData($param,$Axis,$regionColumn=array()){
        //初始化参数
        $code = $param['code'];
        $DataBase = $param['db'];
        $Head = $param['vAxis'];
        
        $xAxis = $Axis['xAxis'];
        $yAxis = $Axis['yAxis'];
        $vAxis = $Axis['vAxis'];
        
        //处理X维度表达式
        $res = $this->setXAxisSelectExp($xAxis,true);
        $xSelect = implode("+'@'+", $res).' as xAxis';
        
        $ySelectAxis = $this->parseAxisCode($yAxis);
        $ySelect = implode(',', $ySelectAxis);
        $vSelect = implode(',', $vAxis).' as counts';
        
        //解析交叉分析之前的SQL
        $OSql = 'select '
                .$ySelect
                .','.$xSelect
                .','.$vSelect
                .' from ('.$DataBase.') as tp ';
        
        //转换成交叉分析表达式
        $ResultAxis = $this->setPivotExp($Head);
        $pAxis = implode(',', $ResultAxis['p']);
        $hAxis = implode(',', $ResultAxis['h']);
        $rAxis = implode(',', $ResultAxis['r']);
        $cAxis = 'sum(counts)';
        
        $PSql ='select '
                .$ySelect
                .','.$hAxis
                .' from ('.$OSql.') as tptptp'
                .' PIVOT('.$cAxis.' for '
                .' xAxis in('.$pAxis.')'
                .' ) as p';
        
        //解析中文含义
        $Inner = $this->getInnerData($code,$yAxis,$regionColumn);
        //解析ID
        if(count($yAxis) > 1){
            $id = implode("+'@'+", $Inner['BCode']).' as id';
            $BCode = implode("+'@'+", $Inner['id']).' as BCode';
        }else{
            $id = implode(',',$Inner['BCode']).' as id ';
            $BCode = implode(',',$Inner['id']).' as BCode ';
        }
        $select = implode(',', $Inner['select']);
        $order = implode(',', $Inner['order']);
        
        $sql = 'select '.$id
                .','.$BCode
                .','.$select
                .','.$rAxis
                .' from ('.$PSql.') as restp '
                .implode(' ', $Inner['inner'])
                .' order by '.$order; 

        $result = M()->query($sql);

        return $result;
    }
    
    /**
     * @获取多个统计值的数据源
     * @param type $param
     * @param type $Axis
     * @param type $regionColumn
     * @return type
     */
    private function setMultiVAxisData($param,$Axis,$regionColumn=array()){
        //初始化参数
        $code = $param['code'];
        $DataBase = $param['db'];
        $Head = $param['vAxis'];
        $decimal = $param['decimal'];
        
        $xAxis = $Axis['xAxis'];
        $yAxis = $this->parseAxisCode($Axis['yAxis']);
        $vAxis = $Axis['vAxis'];        
        
        //处理X维度表达式
        $res = $this->setXAxisSelectExp($xAxis,false);
        $xSelect = implode("+'@'+", $res);
        $ySelect = implode(',', $yAxis);
        
        //解析每种组合的数据源
        foreach ($vAxis as $key){
            //解析交叉分析之前的SQL
            $OSql[] = 'select '
                    .$ySelect
                    .','.$xSelect."+'@'+'".$key."' as xAxis"
                    .','.$key.' as counts'
                    .' from ('.$DataBase.') as tp ';
        }
        
        //创建临时表//返回临时表名
        $temptable=$this->createTempDataTable($yAxis,$decimal);
        $this->tempTableArr[] = $temptable;
        
        //写入临时表
        $yColumn = implode(',', $yAxis);
        $sql = 'insert into '.$temptable.'('.$yColumn.','.'xAxis,counts) ';
        $sql .= implode(' union all ', $OSql);
        M()->execute($sql);
        
        //转换成交叉分析表达式
        $ResultAxis = $this->setPivotExp($Head);
        $pAxis = implode(',', $ResultAxis['p']);
        $hAxis = implode(',', $ResultAxis['h']);
        $rAxis = implode(',', $ResultAxis['r']);
        $cAxis = 'sum(counts)';
        
        $PSql ='select '
                .$ySelect
                .','.$hAxis
                .' from '.$temptable
                .' PIVOT('.$cAxis.' for '
                .' xAxis in('.$pAxis.')'
                .' ) as p';
        
        //解析中文含义
        $yAxis = $Axis['yAxis'];//去掉ID表达式
        $Inner = $this->getInnerData($code,$yAxis,$regionColumn);
        //解析ID
        if(count($yAxis) > 1){
            $id = implode("+'@'+", $Inner['BCode']).' as id';
        }else{
            $id = implode(',',$Inner['BCode']).' as id ';
        }
        $select = implode(',', $Inner['select']);
        $order = implode(',', $Inner['order']);
        
        $sql = 'select '.$id
                .','.$select
                .','.$rAxis
                .' from ('.$PSql.') as restp '
                .implode(' ', $Inner['inner'])
                .' order by '.$order; 

        $result = M()->query($sql);
        
        return $result;
    }

    /**
     * @格式化行数据输出格式【此方法将带右侧合计】
     * @param type $data
     * @return type
     */
    private function setNotXSumDataRowsFormat($data){
        $result = array();//结果
        //追加id值
        $yAxis = $this->yAxis;
        array_push($yAxis, 'id');
        
        //当需要右侧合计时，读取右侧合计值
        if($this->xNums>0){
            if($this->count['isXSum']==1){
                $Rdata = $this->getRightSumData($this->DataBase,$this->yAxis,$this->xAxis,$this->vAxis);

                if($this->levelNums>1){//多层
                    foreach ($Rdata as $val){
                        $id = $val['xAxis'];
                        foreach ($this->vAxis as $v){
                            $key = $this->setCountColumnFormats($v['k'], $v['c']);
                            $RightData[$id][$key] = $val[$key];
                        } 
                    }                
                }else{//单层
                    foreach ($Rdata as $val){
                        $id = $val['xAxis'];
                        foreach($val as $k=>$v){
                            $RightData[$id]['sums'] = $v;
                        }                    
                    }                
                }     
            }
        }

            
        $i=0;
        foreach ($data as $val){
            foreach ($val as $k=>$v){
                if(in_array($k, $yAxis)){
                    $result[$i][$k] = $v;
                }else{
                    $result[$i][$k] = $this->setCodeAccuracy($k,$v);
                }                
            }
            //若需要右侧统计时
            if($this->xNums>0){
                if($this->count['isXSum']==1){
                    if($this->levelNums>1){//多层
                        foreach ($this->vAxis as $value){
                            $key = $this->setCountColumnFormats($value['k'], $value['c']);
                            $result[$i][$key] = round($RightData[$val['id']][$key],$this->AccuracyConfig[$value['k']]);
                        }
                    }else{//单层
                        foreach ($this->vAxis as $value){
                            $key = $value['k'];
                        }
                        $result[$i]['sums'] = round($RightData[$val['id']]['sums'],$this->AccuracyConfig[$key]);
                    }
                }
            }
            ++$i;
        }
        return $result;
    }
    
    
    /**
     * @格式化行数据输出格式【此方法将带右侧合计】
     * @param type $data
     * @return type
     */
    private function setAddSumDataRowsFormat($data){
        $result = array();//结果
        $RightData = array();
        //追加id值
        $yAxis = $this->yAxis;
        array_push($yAxis, 'id');
        
        //当需要右侧合计时，读取右侧合计值
        if($this->xNums>0){
            if($this->count['isXSum']==1){
                $Rdata = $this->getRightSumData($this->DataBase,$this->yAxis,$this->xAxis,$this->vAxis);

                if($this->levelNums>1){//多层
                    foreach ($Rdata as $val){
                        $id = $val['xAxis'];
                        foreach ($this->vAxis as $v){
                            $key = $this->setCountColumnFormats($v['k'], $v['c']);
                            $RightData[$id][$key] = $val[$key];
                        } 
                    }                
                }else{//单层
                    foreach ($Rdata as $val){
                        $id = $val['xAxis'];
                        foreach($val as $k=>$v){
                            $RightData[$id]['sums'] = $v;
                        }                    
                    }                
                }     
            }
        }

            
        $i=0;
        foreach ($data as $val){
            foreach ($val as $k=>$v){
                if(in_array($k, $yAxis)){
                    $result[$i][$k] = $v;
                }else{
                    $result[$i][$k] = $this->setCodeAccuracy($k,$v);
                }                
            }
            //若需要右侧统计时
            if($this->xNums>0){
                if($this->count['isXSum']==1){
                    if($this->levelNums>1){//多层
                        foreach ($this->vAxis as $value){
                            $key = $this->setCountColumnFormats($value['k'], $value['c']);
                            $result[$i][$key] = round($RightData[$val['id']][$key],$this->AccuracyConfig[$value['k']]);
                        }
                    }else{//单层
                        foreach ($this->vAxis as $value){
                            $key = $value['k'];
                        }
                        $result[$i]['sums'] = round($RightData[$val['id']]['sums'],$this->AccuracyConfig[$key]);
                    }
                }
            }
            ++$i;
        }
        return $result;
    }
    
    /**
     * @格式化行数据输出格式【此方法用于带右侧合计】
     * @param type $data
     * @return type
     */
    private function setNotYSumDataRowsFormat($data){
        $result = array();//结果
        $i=0;
        foreach ($data as $val){
            foreach ($val as $k=>$v){
                $result[$i][$k] = $v;           
            }
            ++$i;
        }
        return $result;
    }
    
    
    /**
     * @专门处理计算脚合计时，统计字段的解析
     * @return type
     */
    private function setFootCountFormat($vAxis){
        foreach ($vAxis as $val){
            if($val['c']=='RATE'){//当计算占比时
                $v[] = '100 as '.$this->setCountColumnFormats($val['k'], $val['c']);
            }else{
                $v[] = $val['c'].'('.$this->setCountColumnFormats($val['k'], $val['c']).')'.' as '.$this->setCountColumnFormats($val['k'], $val['c']);
            }            
        }
        $vAxis = implode(',', $v);
        return $vAxis;
    }    
    
    /**
     * @解析FOOT合计数据源
     * @param type $OriginData 基础数据源
     * @param type $xAxis 分组维度
     * @param type $yAxis 统计维度
     * @param type $vAxis 统计值
     * @return type
     */
    private function getFootData($OriginData,$xAxis,$yAxis,$vAxis){
        //初始化参数
        $vAxis = $this->setFootCountFormat($vAxis);
        
        if(count($xAxis)>0){
            if(count($yAxis)>0){//同时存在XY轴
                $Axis = $this->setXAxisSelectExp($xAxis,true);
                $xSelect = implode("+'@'+", $Axis).' as xAxis';
                
                $xSelectAxis = $this->parseAxisCode($xAxis);
                $gRoup = implode(',', $xSelectAxis);
                $order = implode(',', $xAxis);
                
                $sql = 'select '
                    .$xSelect
                    .','.$vAxis 
                    .' from ('
                    .$OriginData
                    .') as foot'
                    .' group by '.$gRoup
                    .' order by '.$order;
            }
        }else{//仅Y轴时
            $sql = 'select '
                    .$vAxis 
                    .' from ('
                    .$OriginData
                    .') as foot';    
        }        
       
        $result = M()->query($sql);

        return $result;
    }
    
    /**
     * @解析右侧合计数据源
     * @param type $OriginData 基础数据源
     * @param type $xAxis 分组维度
     * @param type $yAxis 统计维度
     * @param type $vAxis 统计值
     * @return type
     */
    private function getRightSumData($OriginData,$xAxis,$yAxis,$vAxis){
        //初始化参数
        $vAxis = $this->setFootCountFormat($vAxis);
        
        if(count($xAxis)>0){
            if(count($yAxis)>0){//同时存在XY轴
                $Axis = $this->setXAxisSelectExp($xAxis,true);
                $xSelect = implode("+'@'+", $Axis).' as xAxis';
                
                $xSelectAxis = $this->parseAxisCode($xAxis);
                $gRoup = implode(',', $xSelectAxis);
                
                $sql = 'select '
                    .$xSelect
                    .','.$vAxis 
                    .' from ('
                    .$OriginData
                    .') as foot'
                    .' group by '.$gRoup;
            }
        }else{//仅Y轴时
            $sql = 'select '
                    .$vAxis 
                    .' from ('
                    .$OriginData
                    .') as foot';    
        }        

        $result = M()->query($sql);

        return $result;
    }
    
    /**
     * @解析总合计：右侧脚合计
     * @param type $OriginData
     * @param type $xAxis
     * @param type $yAxis
     * @param type $vAxis
     * @return type
     */
    private function getFootSumData($OriginData,$vAxis){
        //初始化参数
        foreach ($vAxis as $val){
            if($val['c']=='RATE'){//当计算占比时
                $vSum[] = '100 as '.$this->setCountColumnFormats($val['k'], $val['c']);
            }else{
                $vSum[] = $this->setCount($this->AxisConfig,$this->UomConfig,$val);
            }
        }
        
        $vSelect = implode(',', $vSum);
        
        $sql = 'select '
                .$vSelect 
                .' from ('
                .$OriginData
                .') as foot';         
        
        $result = M()->query($sql);
        
        return $result;
    }
    
    /**
     * @解析左侧FOOT表达式
     * @return type
     */
    private function setLeftFoot(){
        //左侧栏目代号
        if($this->xNums>0){
            if($this->yNums>0){
                $field = $this->yAxis[0];
                $Lfoot[$field]=array('f'=>$field,'t'=>$this->AxisConfig['sums']['FieldName'],'c'=>$this->yNums);
            }else{
                $Lfoot['yAxis']=array('f'=>'yAxis','t'=>$this->AxisConfig['sums']['FieldName'],'c'=>1);
            }
        }else{//仅Y轴
            if($this->type==1 && $this->yNums==1){
                $Lfoot['rank']=array('f'=>'rank','t'=>$this->AxisConfig['sums']['FieldName'],'c'=>$this->yNums+1);
            }else{
                $field = $this->yAxis[0];
                $Lfoot[$field]=array('f'=>$field,'t'=>$this->AxisConfig['sums']['FieldName'],'c'=>$this->yNums);
            }
        }
        
        return $Lfoot;
    }
    
    /**
     * @格式化总合计数据
     * @return type
     */
    private function setRightFoot(){
        $data = $this->getFootSumData($this->OriginData,$this->vAxis);
        
        //处理结果标识
        foreach($data as $val){
            foreach ($val as $k=>$v){
                $resData[$k] = $v;
            }
        }
        
        foreach($this->vAxis as $val){
            $key = $this->setCountColumnFormats($val['k'], $val['c']);
            $value = round($resData[$key],$this->AccuracyConfig[$val['k']]);
            
            if($this->vNums>1){
                $Rfoot[$key]=array('f'=>$key,'t'=>$value,'c'=>1);
            }else{
                if($this->levelNums>1){
                    $Rfoot[$key]=array('f'=>$key,'t'=>$value,'c'=>1);
                }else{
                    $Rfoot[$key]=array('f'=>'sums','t'=>$value,'c'=>1);
                }
            }
            
        }
        
        return $Rfoot;
    }

    /**
     * @解析表脚数据输出格式
     * @return type
     */
    private function setDataFootFormat(){        
        $result = array();//结果
        //层级数：仅为1
        $level = 1;
        
        //左侧FOOT
        $Lfoot = $this->setLeftFoot();

        //注意此处顺序，排在前面的为分组项
        $data = $this->getFootData($this->DataBase,$this->xAxis,$this->yAxis,$this->vAxis);
        
        
        //主要值的统计
        if($this->xNums>0){
            if($this->yNums>0){//同时存在XY轴时
                if($this->vNums>1){//多个统计值时
                    foreach($this->vAxis as $val){
                        $vAxis[] = $this->setCountColumnFormats($val['k'], $val['c']);
                    }
                    
                    //将结果转换成K-V格式
                    foreach ($data as $val){
                        foreach ($vAxis as $key){
                            $id = $val['xAxis'].'@'.$key;
                            $resData[$id] = $val[$key];
                        }
                    }
                    
                    foreach($this->DataHead as $key=>$val){
                        $field = $val['f'];
                        $value = $this->setCodeAccuracy($field,$resData[$key]);
                        
                        $Mfoot[$key] = array('f'=>$field,'t'=>$value,'c'=>1);
                    }
                    
                }else{//单个统计值
                    foreach($this->vAxis as $val){
                        $vAxis = $this->setCountColumnFormats($val['k'], $val['c']);
                    }
                    
                    //将结果转换成K-V格式
                    foreach ($data as $val){
                        $id = $val['xAxis'];
                        $resData[$id] = $val[$vAxis];
                    }
                    
                    foreach($this->DataHead as $key=>$val){
                        $field = $val['f'];
                        $value = $this->setCodeAccuracy($field,$resData[$key]);
                        
                        $Mfoot[$key] = array('f'=>$field,'t'=>$value,'c'=>1);
                    }
                }                
            }
            
            //右侧统计
            if($this->count['isXSum']==1){
                $Rfoot = $this->setRightFoot();
            }else{
                $Rfoot = array();
            }
        }else{//仅Y轴
            //将结果转换成K-V格式
            foreach ($data as $val){
                $id = $val['xAxis'];
                $resData[$id] = $val[$vAxis];
            }

            foreach($this->DataHead as $key=>$val){
                $field = $val['f'];
                $value = $this->setCodeAccuracy($field,$resData[$key]);
                
                $Mfoot[$key] = array('f'=>$field,'t'=>$value,'c'=>1); 
            }
        }                
        
        return $this->setHeaderLevelArray($level,$Lfoot,$Mfoot,$Rfoot,1);
    }

    /**
     * @根据维度参数，解析出带ID字段的数组
     * @param type $yAxis
     */
    private function parseAxisCode($yAxis){
        foreach ($yAxis as $kkey){
            switch ($this->AxisConfig[$kkey]['FieldType']){
                case 1:
                    $ySelectAxis[] = $kkey;
                    break;
                case 2:
                    $ySelectAxis[] = $kkey;
                    $ySelectAxis[] = 'D_'.$kkey;                    
                    break;
                case 3:
                    $ySelectAxis[] = $kkey;
                    break;
                case 4:
                    $ySelectAxis[] = $kkey;
                    break;
            }
        }
        return $ySelectAxis;
    }
    
    
    public function test(){
//        var_dump($this->xAxis);
//        var_dump($this->yAxis);
//        var_dump($this->vAxis);
//        var_dump($this->condition);
        $array=$this->getAnalyzeDataResult();
        $param = array('code'=>$this->code,'db'=>$this->DataBase);
        $Axis = array('Axis'=>$this->yAxis,'vAxis'=>$this->vAxis);
        //$r = $this->getTopSingleAxisData($param,$this->ranking,$Axis,$this->regionColumn);
        $r = $this->setNoYAxisResult($array,$this->vAxis);
        return $r;
    }
}
